﻿using System;
using System.Collections.Generic;
using System.Linq;
using DataBaseLayer.Abstractions.Interfaces.Services;
using DataBaseLayer.Dto;
using DataBaseLayer.Extensions;

namespace DataBaseLayer.Services
{
	public class GalleriesService : IGalleriesService
	{
		#region Constants

		private const string SLASH = @"/";
		private const string BACK_SLASH = @"\";

		#endregion

		#region Variables

		private readonly churchDataBase _dataBase;

		#endregion

		#region Constructors

		public GalleriesService(churchDataBase dataBase)
		{
			if (dataBase == null)
				throw new ArgumentNullException(string.Format("data base"));

			_dataBase = dataBase;
		}

		#endregion

		#region IGalleriesService Members

		public IEnumerable<GalleryData> GetImageGalleriesByPageNumber(int pageNumber, int countGalleries)
		{
			return _dataBase.Galleries
				.Where(g => g.IsImagesGallery)
				.OrderByDescending(g => g.GalleryId)
				.Skip(pageNumber*countGalleries)
				.Take(countGalleries)
				.ToDTOs();
		}

		public int GetCountImageGalleries()
		{
			return _dataBase.Galleries.Count(g => g.IsImagesGallery);
		}

		public IEnumerable<GalleryData> GetFotoClubGalleriesByPageNumber(int pageNumber, int countGalleries)
		{
			return _dataBase.Galleries
				.Where(g => g.IsFotoclub)
				.OrderByDescending(g => g.GalleryId)
				.Skip(pageNumber * countGalleries)
				.Take(countGalleries)
				.ToDTOs();
		}

		public int GetCountFotoClubGalleries()
		{
			return _dataBase.Galleries.Count(g => g.IsImagesGallery);
		}

		public GalleryData GetImageGalleryById(int id, int countGalleriesOnPage)
		{
			var result = _dataBase.Galleries.SingleOrDefault(g => g.GalleryId == id).ToDTO();
			if (result != null && result.IsImagesGallery)
			{
				result.PageNumber = _dataBase
					.Galleries
					.Where(g => g.IsImagesGallery)
					.Count(n => n.GalleryId > result.GalleryId) / countGalleriesOnPage + 1;
				return result;
			}

			return null;
		}

		public GalleryData GetFotoClubGalleryById(int id, int countGalleriesOnPage)
		{
			var result = _dataBase.Galleries.SingleOrDefault(g => g.GalleryId == id).ToDTO();
			if (result != null && result.IsFotoclub)
			{
				result.PageNumber = _dataBase
					.Galleries
					.Where(g => g.IsFotoclub)
					.Count(n => n.GalleryId > result.GalleryId) / countGalleriesOnPage + 1;
				return result;
			}

			return null;
		}

		public IEnumerable<GalleryData> GetGalleries()
		{
			return _dataBase.Galleries.ToDTOs();
		}

		public IEnumerable<GalleryData> GetImageGalleries()
		{
			return _dataBase.Galleries.Where(g => g.IsImagesGallery).ToDTOs();
		}

		public IEnumerable<GalleryData> GetFotoclubGalleries()
		{
			return _dataBase.Galleries.Where(g => g.IsFotoclub).ToDTOs();
		}

		public void CreateGallery(GalleryData entity)
		{
			if (entity != null)
			{
				var newGallery = new Gallery
				{
					Name = entity.Name,
					IsFotoclub = entity.IsFotoclub,
					IsImagesGallery = entity.IsImagesGallery
				};
				_dataBase.Galleries.Add(newGallery);
				_dataBase.SaveChanges();
			}
		}

		public void UpdateGallery(GalleryData entity)
		{
			if (entity != null)
			{
				var oldGallery = _dataBase.Galleries.SingleOrDefault(n => n.GalleryId == entity.GalleryId);
				if (oldGallery != null)
				{
					oldGallery.Name = entity.Name;
					oldGallery.IsFotoclub = entity.IsFotoclub;
					oldGallery.IsImagesGallery = entity.IsImagesGallery;
					_dataBase.SaveChanges();
				}
			}
		}

		public void DeleteGallery(int id)
		{
			var galleryForDel = _dataBase.Galleries.SingleOrDefault(n => n.GalleryId == id);
			if (galleryForDel != null)
			{
				_dataBase.Galleries.Remove(galleryForDel);
				_dataBase.SaveChanges();
			}
		}

		public IEnumerable<ImageData> GetGalleryImagesByGalleryId(int id)
		{
			return _dataBase.Images.Where(i => i.Gallery != null && i.Gallery.GalleryId == id).OrderBy(i => i.ImageId).ToDTOs();
		}

		public void UpdateGalleryDefaultImage(int newDefaultImageId, bool isDefaultImage)
		{
			var image = _dataBase.Images.SingleOrDefault(i => i.ImageId == newDefaultImageId);
			if (image != null)
			{
				var images = _dataBase.Images.Where(i => i.GalleryId == image.GalleryId).OrderBy(i => i.ImageId).ToList();
				images.ForEach(i => i.IsDefault = false);
				image.IsDefault = isDefaultImage;
				if (!isDefaultImage)
				{
					var defImage = images.FirstOrDefault();
					if (defImage != null)
						defImage.IsDefault = true;
				}
				_dataBase.SaveChanges();
			}
		}

		public void DeleteImage(int id)
		{
			var image = _dataBase.Images.SingleOrDefault(i => i.ImageId == id);
			if (image != null)
			{
				_dataBase.Images.Remove(image);
				if (image.IsDefault)
				{
					var images = _dataBase.Images.Where(i => i.GalleryId == image.GalleryId && i.ImageId != image.ImageId).OrderBy(i => i.ImageId).ToList();
					images.ForEach(i => i.IsDefault = false);
					var defImage = images.FirstOrDefault();
					if (defImage != null)
						defImage.IsDefault = true;
				}
				_dataBase.SaveChanges();
			}
		}

		public string GetBigImageNameById(int id)
		{
			var image = _dataBase.Images.SingleOrDefault(i => i.ImageId == id);
			var result = string.Empty;
			if (image != null && !string.IsNullOrWhiteSpace(image.Url))
			{
				var num = image.Url.LastIndexOf(SLASH, StringComparison.Ordinal);
				if (num == -1)
					num = image.Url.LastIndexOf(BACK_SLASH, StringComparison.Ordinal);
				if (num != -1)
					result = image.Url.Substring(num + 1);
			}
			return result;
		}

		public string GetSmallImageNameById(int id)
		{
			var image = _dataBase.Images.SingleOrDefault(i => i.ImageId == id);
			var result = string.Empty;
			if (image != null && !string.IsNullOrWhiteSpace(image.UrlThumb))
			{
				var num = image.UrlThumb.LastIndexOf(SLASH, StringComparison.Ordinal);
				if (num == -1)
					num = image.UrlThumb.LastIndexOf(BACK_SLASH, StringComparison.Ordinal);
				if (num != -1)
					result = image.UrlThumb.Substring(num + 1);
			}
			return result;
		}

		public int GetLastImageNumber()
		{
			var lastImage = _dataBase.Images.OrderByDescending(i => i.ImageId).FirstOrDefault();
			return lastImage != null ? lastImage.ImageId : 1;
		}

		public void CreateImage(ImageData image)
		{
			if (image != null)
			{
				var newImage = new Image
				{
					GalleryId = image.GalleryId,
					Url = image.Url,
					UrlThumb = image.UrlThumb,
					IsDefault = !_dataBase.Images.Any(i => i.GalleryId == image.GalleryId)
				};
				_dataBase.Images.Add(newImage);
				_dataBase.SaveChanges();
			}
		}

		#endregion
	}
}
